﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Security.Cryptography;

namespace Zanox.Api.Client.Auth.V20110501
{
    /// <summary>
    /// This class implements a Hash-based signature according to the RFC2616 for HTTP Digest Access Authentication and the RFC2104 for Keyed-Hashing for Message Authentication standard.
    /// </summary>
    public class Signature
    {        
        /// <summary>
        /// Authentication to validate your requests to the zanox SOAP API.
        /// </summary>
        /// <param name="datetime">Current Datetime</param>
        /// <param name="sharedKey">Your Shared Key. You can get one at www.zanox.com</param>
        /// <param name="service">Name of the service to signate, e.g. "publisherservice"</param>
        /// <param name="operation">name of the operation to signate, e.g. "getadspaces"</param>
        /// <returns>Returns Signature for zanox Web Services SOAP API</returns>
        public static string SoapSignature(DateTime datetime, string secretKey, string service, string operation, string nonce)
        {
            HMACSHA1 crypto = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey));
            string date = GetZDateTime(datetime);
            string canonical = service + operation + date + nonce;
            string signature = System.Convert.ToBase64String(crypto.ComputeHash(Encoding.UTF8.GetBytes(canonical)));
            return signature;
        }

        /// <summary>
        /// Authentication to validate your requests to the zanox RESTful API.
        /// </summary>
        /// <param name="datetime">Current Datetime</param>
        /// <param name="sharedKey">Your Shared Key. You can get one at www.zanox.com</param>
        /// <param name="httpVerb">Name of the service to signate, e.g. "publisherservice"</param>
        /// <param name="uri">The URI has to be included without the protocol (json/xml/soap) and version parameter. Example: "/xml/2008-07-21/adspaces" becomes just "/adspaces".</param>
        /// <returns>Returns Signature for zanox Web Services RESTful API</returns>
        public static string RestSignature(DateTime datetime, string secretKey, string httpVerb, string uri, string nonce)
        {
            HMACSHA1 crypto = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey));
            string date = GetGMTDateTime(datetime);
            string canonical = httpVerb + uri + date + nonce;
            string signature = System.Convert.ToBase64String(crypto.ComputeHash(Encoding.UTF8.GetBytes(canonical)));
            return signature;
        }

        public static string GetGMTDateTime(DateTime dateTime)
        {
            CultureInfo culture = new CultureInfo("en-US");
            return dateTime.AddHours(-1).ToString("ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", culture);
        }

        public static string GetZDateTime(DateTime dateTime)
        {
            CultureInfo culture = new CultureInfo("en-US");
            return dateTime.ToString("yyyy-MM-ddTHH:mm:ss.000Z", culture);
        }

        /// <summary>
        /// Generate a random string. Has to be unique within 30minutes. Minimum 20 characters.
        /// </summary>
        public static string GetNonce()
        {
            string returnValue = Guid.NewGuid().ToString();
            return returnValue;
        }
    }
}
